﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Cesave.Domain.PermisosModule.Contracts.CiclosFechas;
using Cesave.Infrastructure.CrossCutting.IoC;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Domain.Core.Specification;
using Cesave.Domain.Core;

namespace Cesave.Domain.PermisosModule.Tests.ServicesTests
{
	[TestClass]
	[DeploymentItem("Cesave.Infrastructure.Data.PermisosModule.Mock.dll")]
	[DeploymentItem("Cesave.Infrastructure.Data.PermisosModule.dll")]
	public class CiclosFechaServiceTests
	{
		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException))]
		public void AddCiclosFecha_Null_CiclosFecha_Throws_ArgumentNullException()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			// Act
			service.AddCiclosFecha(null);
		}

		[TestMethod]
		public void AddCiclosFecha_Invoke()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			var guid = Guid.NewGuid();

			var expected = new CiclosFecha
			{
				CicloGuid = new Guid("ED77E3AC-1E91-44EA-9F80-C9B2619B9211"),
				JuntaGuid = new Guid("C1F6907F-9F13-46EA-981E-2E6DB652AAF2"),
				JuntaId = 2,
				CicloId = 2,
				FechaGuid = guid,
				FechaId = 99,
				Inicio = new DateTime(2010, 8, 1),
				Fin = new DateTime(2010, 8, 15),
				Nombre = "TEST",
				Status = true,
			};

			// Act
			service.AddCiclosFecha(expected);

			ICiclosFechaRepository repository = IoCFactory.Resolve<ICiclosFechaRepository>();
			Specification<CiclosFecha> spec = new DirectSpecification<CiclosFecha>(f => f.FechaGuid == guid);
			var actual = repository.GetBySpec(spec).FirstOrDefault();

			// Assert
			Assert.IsNotNull(actual);
			Assert.AreEqual(expected, actual);

			// clean
			IUnitOfWork unitOfWork = repository.StoreContext;
			repository.Remove(actual);
			unitOfWork.Commit();
			Assert.IsNull(repository.GetBySpec(spec).FirstOrDefault());
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException))]
		public void ChangeCiclosFecha_Null_CiclosFecha_Throws_ArgumentNullException()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();
			ICiclosFechaRepository repository = IoCFactory.Resolve<ICiclosFechaRepository>();

			// Act
			service.ChangeCiclosFecha(null);
		}

		[TestMethod]
		public void ChangeCiclosFecha_Invoke()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();
			ICiclosFechaRepository repository = IoCFactory.Resolve<ICiclosFechaRepository>();

			var guid = new Guid("A827881A-8EC9-4187-879A-192BEF55A0F6");
			Specification<CiclosFecha> spec = new DirectSpecification<CiclosFecha>(f => f.FechaGuid == guid);
			var expected = repository.GetBySpec(spec).FirstOrDefault();
			expected.Nombre = "TEST";
			// Act
			service.ChangeCiclosFecha(expected);

			var actual = repository.GetBySpec(spec).FirstOrDefault();

			// Assert
			Assert.IsNotNull(actual);
			Assert.AreEqual("TEST", actual.Nombre);

			// clean
			string nombre = "1A QUINC. DE JUNIO";
			actual.Nombre = nombre;
			service.ChangeCiclosFecha(actual);
			Assert.AreEqual(nombre, repository.GetBySpec(spec).FirstOrDefault().Nombre);
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void FindCiclosFechasByJunta_Empty_Guid_Throws_ArgumentException()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			// Act
			var actual = service.FindCiclosFechasByJunta(Guid.Empty);
		}

		[TestMethod]
		public void FindCiclosFechasByJunta_Invoke()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			var guid = new Guid("C1F6907F-9F13-46EA-981E-2E6DB652AAF2");

			// Act
			var actual = service.FindCiclosFechasByJunta(guid);

			// Assert
			Assert.IsNotNull(actual);
			actual.ToList().ForEach(a =>
			{
				Assert.AreEqual(guid, a.JuntaGuid);
			});
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void FindCiclosFechasByJuntaAndCiclo_Empty_Guid_Throws_ArgumentException()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			// Act
			var actual = service.FindCiclosFechasByJuntaAndCiclo(Guid.Empty, Guid.Empty);
		}

		[TestMethod]
		public void FindCiclosFechasByJuntaAndCiclo_Invoke()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			var juntaGuid = new Guid("C1F6907F-9F13-46EA-981E-2E6DB652AAF2");
			var cicloGuid = new Guid("ED77E3AC-1E91-44EA-9F80-C9B2619B9211");

			// Act
			var actual = service.FindCiclosFechasByJuntaAndCiclo(juntaGuid, cicloGuid);

			// Assert
			Assert.IsNotNull(actual);
			actual.ToList().ForEach(a =>
			{
				Assert.AreEqual(juntaGuid, a.JuntaGuid);
				Assert.AreEqual(cicloGuid, a.CicloGuid);
			});
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void FindCiclosFechasByJuntaAndDateRange_Empty_Guid_Throws_ArgumentException()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			// Act
			var actual = service.FindCiclosFechasByJuntaAndDateRange(Guid.Empty, DateTime.Now, DateTime.Now);
		}

		[TestMethod]
		[ExpectedException(typeof(InvalidOperationException))]
		public void FindCiclosFechasByJuntaAndDateRange_Min_DateTime_Value_Throws_InvalidOperationException()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			// Act
			var actual = service.FindCiclosFechasByJuntaAndDateRange(Guid.NewGuid(), DateTime.MinValue, DateTime.MinValue);
		}

		[TestMethod]
		public void FindCiclosFechasByJuntaAndDateRange_Invoke()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			var juntaGuid = new Guid("C1F6907F-9F13-46EA-981E-2E6DB652AAF2");
			var fromDate = new DateTime(2010, 06, 01);
			var toDate = new DateTime(2010, 06, 20);

			// Act
			var actual = service.FindCiclosFechasByJuntaAndDateRange(juntaGuid, fromDate, toDate);

			// Assert
			Assert.IsTrue(0 < actual.Count());
			actual.ForEach(a =>
			{
				Assert.AreEqual(juntaGuid, a.JuntaGuid);
				Assert.IsTrue(fromDate <= a.Inicio);
				Assert.IsTrue(toDate >= a.Fin);
			});
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void FindCiclosFechasByCicloAndDateRange_Empty_Guid_Throws_ArgumentException()
		{
			// Arrange
			ICiclosFechaService service = IoCFactory.Resolve<ICiclosFechaService>();

			// Act
			var actual = service.FindCiclosFechasByCicloAndDateRange(Guid.Empty, DateTime.Now, DateTime.Now);
		}

	}
}
